#include "prefix.hpp"

inline uint32_t mask32( uint32_t value, int8_t masklen )  {
    return value & (~(((uint64_t)0xFFFFFFFF) >> masklen) );
}

Prefix::Prefix() { ip = 0, netmask = 0; }
Prefix::Prefix(uint32_t _ip, uint8_t _netmask) {
    ip = mask32( _ip, _netmask);
    netmask = _netmask;
//            debugsn("Prefix new " << hex<< _ip << "/" << dec << (uint32_t)_netmask);
//            debugsn("           " << hex<<  ip << "/" << dec << (uint32_t) netmask);
}

Prefix::~Prefix() {
//            debugsn("~Prefix " << this->str() );
}

uint32_t Prefix::getIP() { return ip; }
uint8_t  Prefix::getNetmask() { return netmask; }

/* get prefix bit, starting from MSB (nbit=0 -> MSB bit in ip , nbit=31 -> LSB bit ) 
   return -1 if tried to access bit out of the netmask */
int Prefix::getBit(uint32_t nbit) {
    if (nbit >= netmask) return -1;
    return BIT_TEST( ip, 31-nbit) ? 1 : 0;
}

bool Prefix::operator<( Prefix rhs ) const {
    if ( this->ip      < rhs.ip ) return true;
    if ( this->netmask < rhs.netmask ) return true;
    return false;
}

Prefix Prefix::operator=( Prefix rhs ) {
    if ( this == &rhs ) return *this;
    ip = rhs.ip;
    netmask = rhs.netmask;
    return *this;
}

bool Prefix::operator==( Prefix rhs ) const {
    return ( ip == rhs.ip) && ( netmask == rhs.netmask);
}

string Prefix::str() const {
    ostringstream oss;
    oss << BYTE3(ip) << "." << BYTE2(ip) <<"."
        << BYTE1(ip) << "." << BYTE0(ip) << "/" <<  (uint32_t)netmask;
    return oss.str();
}










